package jmu.edu.yjc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jmu.edu.yjc.Utils.RedisCache;
import jmu.edu.yjc.domain.ResponseResult;
import jmu.edu.yjc.domain.entity.Keywords;
import jmu.edu.yjc.domain.vo.PageVo;
import jmu.edu.yjc.domain.vo.common.EChartsVo;
import jmu.edu.yjc.domain.vo.common.TagVo;
import jmu.edu.yjc.domain.vo.common.TypeVo;
import jmu.edu.yjc.domain.vo.keyword.DeleteVo;
import jmu.edu.yjc.exception.SystemException;
import jmu.edu.yjc.mapper.KeywordsMapper;
import jmu.edu.yjc.service.KeywordsService;
import jmu.edu.yjc.service.answer.QuestionClassifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 关键字表(Keywords)表服务实现类
 *
 * @author makejava
 * @since 2023-03-15 23:26:04
 */
@Service("keywordsService")
public class KeywordsServiceImpl extends ServiceImpl<KeywordsMapper, Keywords> implements KeywordsService {
    private static Logger logger = LoggerFactory.getLogger(KeywordsServiceImpl.class);
    public static Map<String,String> wordMeanCnMap = new HashMap<>();
    public static Set<String> updateWordType = new HashSet<>();
    private static volatile AtomicBoolean LOCK = new AtomicBoolean(false);
    @Resource
    private RedisCache redisCache;

    @Override
    public List<String> getAllWordType() {
        return baseMapper.getAllWordType();
    }

    @Override
    public List<String> queryKeywordsByWordType(String wordType) {
        return baseMapper.queryKeywordsByWordType(wordType);
    }

    @Override
    public ResponseResult keywordList(Integer pageNum, Integer pageSize, String wordType, String keyword) {
        LambdaQueryWrapper<Keywords> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.hasText(wordType),Keywords::getWordType,wordType);
        wrapper.like(StringUtils.hasText(keyword),Keywords::getKeyword,keyword);
        Page<Keywords> page = new Page<>(pageNum,pageSize);
        page(page,wrapper);
        return ResponseResult.okResult(new PageVo(page.getRecords(),page.getTotal()));
    }

    @Override
    public ResponseResult randomTags() {
        List<String> wordTypes = getAllWordType();
        Random random = new Random();
        //获取一个随机类型
        String wordType = wordTypes.get(random.nextInt(wordTypes.size()));
        List<String> keywords = redisCache.getCacheObject(wordType);
        int i = 0 ;
        List<TagVo> vos = new ArrayList<>();
        while (i < 20 && i < keywords.size()){
            TagVo keyWordVo = new TagVo(i,keywords.get(i));
            vos.add(keyWordVo);
            i++;
        }
        return ResponseResult.okResult(new EChartsVo(vos,wordMeanCnMap.get(wordType)));
    }

    @Override
    public List<Keywords> getAllWordTypeAndCnMean() {
        return baseMapper.getAllWordTypeAndCnMean();
    }

    @Override
    public ResponseResult fullTag() {
        List<TypeVo> list = redisCache.getCacheObject("typeList");
        return ResponseResult.okResult(list);
    }

    @Override
    public boolean isExistKeyword(String keyword, String wordType) {
        LambdaQueryWrapper<Keywords> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Keywords::getWordType,wordType);
        wrapper.eq(Keywords::getKeyword,keyword);
        return count(wrapper)>0;
    }
    @Override
    public synchronized ResponseResult addUpdateWordType(Keywords keywords){
        logger.info("新增Keyword: {}",keywords.toString());
        if (!LOCK.compareAndSet(false,true)) {
            return ResponseResult.okResult(-1,"正在执行同步任务请稍后");
        }
        try {
            updateWordType.add(keywords.getWordType());
            save(keywords);
        }catch (Exception e){
            e.printStackTrace();
            throw new SystemException("插入失败："+ e.getMessage());
        } finally {
            LOCK.set(false);
        }
        return ResponseResult.okResult();
    }
    @Override
    public synchronized  ResponseResult updateRedisCache() {
        logger.info("更新缓存: {}",updateWordType);
        if (!LOCK.compareAndSet(false,true)) {
            return ResponseResult.okResult(-1,"正在执行同步任务请稍后");
        }
        try {

            if(updateWordType.size()>0){
                for (String wordType : updateWordType) {
                    List<String> keywords = queryKeywordsByWordType(wordType);
                    redisCache.setCacheObject(wordType,keywords);
                }
                updateWordType.clear();
            }
            QuestionClassifier.initKeywords();
        }catch (Exception e){
            e.printStackTrace();
            throw new SystemException("更新缓存失败："+ e.getMessage());
        }finally {
            LOCK.set(false);
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult deleteKeywords(DeleteVo deleteVo) {
        logger.info("删除Keyword: {}",deleteVo.toString());
        if (!LOCK.compareAndSet(false,true)) {
            return ResponseResult.okResult(-1,"正在执行同步任务请稍后");
        }
        try {
            List<String> wordTypes = deleteVo.getWordTypes();
            updateWordType.addAll(wordTypes);
            removeByIds(deleteVo.getIds());
        }catch (Exception e){
            e.printStackTrace();
            throw new SystemException("删除失败："+ e.getMessage());
        } finally {
            LOCK.set(false);
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult updateKeywords(Keywords keywords) {
        logger.info("更新Keyword: {}",keywords.toString());
        if (!LOCK.compareAndSet(false,true)) {
            return ResponseResult.okResult(-1,"正在执行同步任务请稍后");
        }
        try {
            //旧的
            Keywords keyword = getById(keywords.getId());
            updateWordType.add(keyword.getWordType());
            updateWordType.add(keywords.getWordType());
            //新的
            updateById(keywords);
        }catch (Exception e){
            e.printStackTrace();
            throw new SystemException("更新失败："+ e.getMessage());
        } finally {
            LOCK.set(false);
        }
        return ResponseResult.okResult();
    }
}
